package edu.umn.se.trap;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import databases.GrantDB;


import databases.KeyNotFoundException;
import databases.PerDiemDB;
import databases.GrantDB.GRANT_FIELDS;
import databases.PerDiemDB.RATE_FIELDS;
import databases.UserDB;
import databases.UserDB.USER_FIELDS;
import databases.UserGrantDB;
import databases.UserGrantDB.USER_GRANT_FIELDS;
import edu.umn.se.trap.exceptions.TrapException;

/**
 * 
 * @author Kevin and Lee
 *
 */
public class Form {    
    /**
     * the input data for the form
     */
    private Map<String, String> myFormData;
    
    /**
     * the output data for the form
     */
    private Map<String, String> myFormOutput;
    
    /**
     * the intermediate form data 
     */
    private TravelDetails travelDetails;
    private Vector<Day> days;
    private Vector<Grant> grants;
    private Vector<Transportation> transportation;
    private Vector<OtherExpenses> otherExpenses;
    private Vector<Destination> destinations;
    private int destCounter;
       
    private TravelFormMetadata formStatus;
    
    /**
     * @param formData - the input data for the form
     * @param description - the description of the form
     */
    public Form(Map<String, String> formData, String description){
        myFormData = formData;
        formStatus = new TravelFormMetadata();
        formStatus.description = description;
        formStatus.status = TravelFormProcessorIntf.FORM_STATUS.DRAFT;
        destCounter = 0;
        days = new Vector<Day>();
        grants = new Vector<Grant>();
        transportation = new Vector<Transportation>();
        otherExpenses = new Vector<OtherExpenses>();
        destinations = new Vector<Destination>();
        myFormOutput = new HashMap<String, String>();
    }
    /**
     * @return the form's description
     */
    public String getFormDescription(){
        return formStatus.description;
    }
    /**
     * @return the raw input data
     */
    public Map<String, String> getFormData(){
        return myFormData;
    }
    
    public void setTravelDetails(TravelDetails TD)
    {
        travelDetails = TD;
    }
    
    public void addDay(Day day)
    {
        days.add(day);
    }
    
    public void addGrant(Grant grant)
    {
        grants.add(grant);
    }
    
    public void addTransportation(Transportation transport)
    {
        transportation.add(transport);
    }
    
    public void addOtherExpenses(OtherExpenses otherExps)
    {
        otherExpenses.add(otherExps);
    }
    
    public void addDestination(Destination dest)
    {
    	if(!(dest.getCity().equals("") && dest.getState().equals("") && dest.getCountry().equals("")))
    	{
	    	destinations.add(dest);
	        destCounter++;
	        this.addToOutputMap("DESTINATION"+Integer.toString(destCounter)+"_CITY", dest.getCity());
	        if(!dest.getState().equals(""))
	        {
	            this.addToOutputMap("DESTINATION"+Integer.toString(destCounter)+"_STATE", dest.getState());
	        }
	        this.addToOutputMap("DESTINATION"+Integer.toString(destCounter)+"_COUNTRY", dest.getCountry());
    	}
    }
    
    public TravelDetails getTravelDetails()
    {
        return travelDetails;
    }
    
    public Vector<Day> getDays()
    {
        return days;
    }
    
    public Vector<Grant> getGrants()
    {
        return grants;
    }
    
    public Vector<Transportation> getTransportation()
    {
        return transportation;
    }
    
    public Vector<OtherExpenses> getOtherExpenses()
    {
        return otherExpenses;
    }
    
    public Vector<Destination> getDestinations()
    {
        return destinations;
    }
    
    public void addToOutputMap(String key, String value)
    {
        myFormOutput.put(key, value);
    }
    
    public Map<String, String> generateOutput() throws TrapException
    {
    	try 
    	{
    		double totalReimbursement = 0;
    		 		
	    	UserDB userDB =  new UserDB();
	    	GrantDB grantDB = new GrantDB();
	    	UserGrantDB userGrantDB = new UserGrantDB();
	    	PerDiemDB perDiemDB = new PerDiemDB();
	    		    	
			List<String> userInfo = userDB.getUserInfo(travelDetails.getUsername());			
	    	    	
	    	// add the sizes of our data vectors
	    	this.addToOutputMap("NUM_DESTINATIONS", String.valueOf(destinations.size()));
	    	this.addToOutputMap("NUM_DAYS", String.valueOf(days.size()));
	    	this.addToOutputMap("NUM_TRANSPORTATION", String.valueOf(transportation.size()));
	    	this.addToOutputMap("NUM_OTHER_EXPENSES", String.valueOf(otherExpenses.size()));
	    	this.addToOutputMap("NUM_GRANTS", String.valueOf(grants.size()));
	    	
	    	// add basic user information
	    	this.addToOutputMap("NAME", userInfo.get(USER_FIELDS.FULL_NAME.ordinal()));
	    	this.addToOutputMap("USER_NAME", travelDetails.getUsername());
	    	this.addToOutputMap("EMAIL", userInfo.get(USER_FIELDS.EMAIL.ordinal()));
	    	this.addToOutputMap("CITIZENSHIP", userInfo.get(USER_FIELDS.CITIZENSHIP.ordinal()));
	    	
	    	if(!userInfo.get(USER_FIELDS.CITIZENSHIP.ordinal()).equalsIgnoreCase("united states"))
	    		this.addToOutputMap("VISA_STATUS", userInfo.get(USER_FIELDS.VISA_STATUS.ordinal()));
	    	DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd HHmmss");
	        Date date = new Date();
	    	this.addToOutputMap("FORM_SUBMISSION_DATETIME", dateFormat.format(date));
	    	this.addToOutputMap("DEPARTURE_DATETIME", myFormData.get("DEPARTURE_DATETIME"));
	    	this.addToOutputMap("ARRIVAL_DATETIME", myFormData.get("ARRIVAL_DATETIME"));
	    	this.addToOutputMap("PAID_BY_UNIVERSITY", userInfo.get(USER_FIELDS.PAID_BY_UNIVERSITY.ordinal()).toLowerCase());
	    	this.addToOutputMap("EMERGENCY_CONTACT_NAME", myFormData.get("EMERGENCY_CONTACT_NAME"));
	    	this.addToOutputMap("EMERGENCY_CONTACT_PHONE", myFormData.get("EMERGENCY_CONTACT_PHONE"));
	    	this.addToOutputMap("JUSTIFICATION_PRESENTED", myFormData.get("JUSTIFICATION_PRESENTED"));
	    	this.addToOutputMap("JUSTIFICATION_CONFERENCE_TITLE", myFormData.get("JUSTIFICATION_CONFERENCE_TITLE"));
	    	this.addToOutputMap("JUSTIFICATION_SPONSORED", myFormData.get("JUSTIFICATION_SPONSORED"));
	    	
	    	if(myFormData.get("TRAVEL_TYPE_CSE_SPONSORED") != null)
	    		this.addToOutputMap("TRAVEL_TYPE_CSE_SPONSORED", myFormData.get("TRAVEL_TYPE_CSE_SPONSORED"));
	    	
	    	if(myFormData.get("TRAVEL_TYPE_DTC_SPONSORED") != null)
		    	this.addToOutputMap("TRAVEL_TYPE_DTC_SPONSORED", myFormData.get("TRAVEL_TYPE_DTC_SPONSORED"));
	    	
	    	if(myFormData.get("TRAVEL_TYPE_NONSPONSORED") != null)
		    	this.addToOutputMap("TRAVEL_TYPE_NONSPONSORED", myFormData.get("TRAVEL_TYPE_NONSPONSORED"));
	    	
	    	if(myFormData.get("JUSTIFICATION_PRESENTED").equalsIgnoreCase("yes"))
	    	{	
	    		this.addToOutputMap("JUSTIFICATION_PRESENTATION_ABSTRACT", myFormData.get("JUSTIFICATION_PRESENTATION_ABSTRACT"));
		    	this.addToOutputMap("JUSTIFICATION_NONSPONSORED", myFormData.get("JUSTIFICATION_NONSPONSORED"));
		    	this.addToOutputMap("JUSTIFICATION_PRESENTATION_TITLE", myFormData.get("JUSTIFICATION_PRESENTATION_TITLE"));
		    	this.addToOutputMap("JUSTIFICATION_PRESENTATION_ACKNOWLEDGEMENT", myFormData.get("JUSTIFICATION_PRESENTATION_ACKNOWLEDGEMENT"));
	    	}
	    	
	    	// add days        
            for (int i = 0; i < days.size(); i++)
            {
               double dayTotal = 0;
      
               Day day = days.get(i);
               this.addToOutputMap("DAY"+Integer.toString(i+1)+"_DATE", day.getDate());
               Meal breakfast = day.getBreakfast();
               Meal lunch = day.getLunch();
               Meal dinner = day.getDinner();
               Lodging lodging = day.getLodging();
               Incidental incidental = day.getIncidentals();
               double rateMultiplier = (i==0 || i+1 == days.size()) ? 0.75:1.0;
               
               // get breakfast 
               if (!breakfast.getCity().equals("") && !breakfast.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(breakfast.getCity(), breakfast.getState());
            	   Double breakfastAmount = perDiemInfo.get(RATE_FIELDS.BREAKFAST_RATE.ordinal());
            	   dayTotal += breakfastAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += breakfastAmount.doubleValue() * rateMultiplier;
               }
               else if (breakfast.getCity().equals("") && !breakfast.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(breakfast.getState());
            	   Double breakfastAmount = perDiemInfo.get(RATE_FIELDS.BREAKFAST_RATE.ordinal());
            	   dayTotal += breakfastAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += breakfastAmount.doubleValue() * rateMultiplier;
               }
               else if (breakfast.getCity().equals("") && breakfast.getState().equals("") && !breakfast.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = null;
            	   if(breakfast.getCountry().equalsIgnoreCase("united states") || breakfast.getCountry().equalsIgnoreCase("usa"))
            	   {
            		   perDiemInfo = perDiemDB.getDomesticPerDiem(breakfast.getCountry());
            	   }
            	   else 
                   {
            	       perDiemInfo = perDiemDB.getInternationalPerDiem(breakfast.getCountry());
                   }
            	   Double breakfastAmount = perDiemInfo.get(RATE_FIELDS.BREAKFAST_RATE.ordinal());
            	   dayTotal += breakfastAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += breakfastAmount.doubleValue() * rateMultiplier;
               }
               else if (!breakfast.getCity().equals("") && breakfast.getState().equals("") && !breakfast.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = null;
            	   if(breakfast.getCountry().equalsIgnoreCase("united states") || breakfast.getCountry().equalsIgnoreCase("usa"))
            	   {
            		   perDiemInfo = perDiemDB.getDomesticPerDiem(breakfast.getCity(), breakfast.getCountry());
            	   }
            	   else 
                   {
            	       perDiemInfo = perDiemDB.getInternationalPerDiem(breakfast.getCity(), breakfast.getCountry());
                   }
            	   Double breakfastAmount = perDiemInfo.get(RATE_FIELDS.BREAKFAST_RATE.ordinal());
            	   dayTotal += breakfastAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += breakfastAmount.doubleValue() * rateMultiplier;
               }
               
               // get lunch 
               if (!lunch.getCity().equals("") && !lunch.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(lunch.getCity(), lunch.getState());
            	   Double lunchAmount = perDiemInfo.get(RATE_FIELDS.LUNCH_RATE.ordinal());
            	   dayTotal += lunchAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += lunchAmount.doubleValue() * rateMultiplier;
               }
               else if (lunch.getCity().equals("") && !lunch.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(lunch.getState());
            	   Double lunchAmount = perDiemInfo.get(RATE_FIELDS.LUNCH_RATE.ordinal());
            	   dayTotal += lunchAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += lunchAmount.doubleValue() * rateMultiplier;
               }
               else if (lunch.getCity().equals("") && lunch.getState().equals("") && !lunch.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = null;
            	   if(lunch.getCountry().equalsIgnoreCase("united states") || lunch.getCountry().equalsIgnoreCase("usa"))
            	   {
            		   perDiemInfo = perDiemDB.getDomesticPerDiem(lunch.getCountry());
            	   }
            	   else 
                   {
            	       perDiemInfo = perDiemDB.getInternationalPerDiem(lunch.getCountry());
                   }
            	   Double lunchAmount = perDiemInfo.get(RATE_FIELDS.LUNCH_RATE.ordinal());
            	   dayTotal += lunchAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += lunchAmount.doubleValue() * rateMultiplier;
               }
               else if (!lunch.getCity().equals("") && lunch.getState().equals("") && !lunch.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = null;
            	   if(lunch.getCountry().equalsIgnoreCase("united states") || lunch.getCountry().equalsIgnoreCase("usa"))
            	   {
            		   perDiemInfo = perDiemDB.getDomesticPerDiem(lunch.getCity(), lunch.getCountry());
            	   }
            	   else 
                   {
            	       perDiemInfo = perDiemDB.getInternationalPerDiem(lunch.getCity(), lunch.getCountry());
                   }
            	   Double lunchAmount = perDiemInfo.get(RATE_FIELDS.LUNCH_RATE.ordinal());
            	   dayTotal += lunchAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += lunchAmount.doubleValue() * rateMultiplier;
               }
               
               // get dinner 
               if (!dinner.getCity().equals("") && !dinner.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(dinner.getCity(), dinner.getState());
            	   Double dinnerAmount = perDiemInfo.get(RATE_FIELDS.DINNER_RATE.ordinal());
            	   dayTotal += dinnerAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += dinnerAmount.doubleValue() * rateMultiplier;
               }
               else if (dinner.getCity().equals("") && !dinner.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(dinner.getState());
            	   Double dinnerAmount = perDiemInfo.get(RATE_FIELDS.DINNER_RATE.ordinal());
            	   dayTotal += dinnerAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += dinnerAmount.doubleValue() * rateMultiplier;
               }
               else if (dinner.getCity().equals("") && dinner.getState().equals("") && !dinner.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = null;
            	   if(dinner.getCountry().equalsIgnoreCase("united states") || dinner.getCountry().equalsIgnoreCase("usa"))
            	   {
            		   perDiemInfo = perDiemDB.getDomesticPerDiem(dinner.getCountry());
            	   }
            	   else 
                   {
            	       perDiemInfo = perDiemDB.getInternationalPerDiem(lunch.getCountry());
                   }
            	   Double dinnerAmount = perDiemInfo.get(RATE_FIELDS.DINNER_RATE.ordinal());
            	   dayTotal += dinnerAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += dinnerAmount.doubleValue() * rateMultiplier;
               }
               else if (!dinner.getCity().equals("") && dinner.getState().equals("") && !dinner.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = null;
            	   if(lunch.getCountry().equalsIgnoreCase("united states") || lunch.getCountry().equalsIgnoreCase("usa"))
            	   {
            		   perDiemInfo = perDiemDB.getDomesticPerDiem(dinner.getCity(), dinner.getCountry());
            	   }
            	   else 
                   {
            	       perDiemInfo = perDiemDB.getInternationalPerDiem(dinner.getCity(), dinner.getCountry());
                   }
            	   Double dinnerAmount = perDiemInfo.get(RATE_FIELDS.DINNER_RATE.ordinal());
            	   dayTotal += dinnerAmount.doubleValue() * rateMultiplier;
            	   totalReimbursement += dinnerAmount.doubleValue() * rateMultiplier;
               }
               
               // get lodging
               if (!lodging.getCity().equals("") && !lodging.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(lodging.getCity(), lodging.getState());
            	   Double lodgingAmount = perDiemInfo.get(RATE_FIELDS.LODGING_CEILING.ordinal());
            	   if (lodging.getAmount() > lodgingAmount)
            	   {
            		   throw new TrapException("Lodging limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += lodging.getAmount();
                	   totalReimbursement += lodging.getAmount();
            	   }
               }
               else if (lodging.getCity().equals("") && !lodging.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(lodging.getState());
            	   Double lodgingAmount = perDiemInfo.get(RATE_FIELDS.LODGING_CEILING.ordinal());
            	   if (lodging.getAmount() > lodgingAmount)
            	   {
            		   throw new TrapException("Lodging limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += lodging.getAmount();
                	   totalReimbursement += lodging.getAmount();
            	   }
               }
               else if (lodging.getCity().equals("") && lodging.getState().equals("") && !lodging.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(breakfast.getCountry());
            	   Double lodgingAmount = perDiemInfo.get(RATE_FIELDS.LODGING_CEILING.ordinal());
            	   if (lodging.getAmount() > lodgingAmount)
            	   {
            		   throw new TrapException("Lodging limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += lodging.getAmount();
                	   totalReimbursement += lodging.getAmount();
            	   }
               }
               else if (!lodging.getCity().equals("") && lodging.getState().equals("") && !lodging.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(lodging.getCity(), lodging.getCountry());
            	   Double lodgingAmount = perDiemInfo.get(RATE_FIELDS.LODGING_CEILING.ordinal());
            	   if (lodging.getAmount() > lodgingAmount)
            	   {
            		   throw new TrapException("Lodging limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += lodging.getAmount();
                	   totalReimbursement += lodging.getAmount();
            	   }
               }
               
               // get incidental
               if (!incidental.getCity().equals("") && !incidental.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(incidental.getCity(), incidental.getState());
            	   Double incidentalPerDiem = perDiemInfo.get(RATE_FIELDS.INCIDENTAL_CEILING.ordinal());
            	   if (incidental.getAmount() > incidentalPerDiem)
            	   {
            		   throw new TrapException("Incidental limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += incidental.getAmount();
                	   totalReimbursement += incidental.getAmount();
            	   }
               }
               else if (incidental.getCity().equals("") && !incidental.getState().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(incidental.getState());
            	   Double incidentalPerDiem = perDiemInfo.get(RATE_FIELDS.INCIDENTAL_CEILING.ordinal());
            	   if (incidental.getAmount() > incidentalPerDiem)
            	   {
            		   throw new TrapException("Incidental limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += incidental.getAmount();
                	   totalReimbursement += incidental.getAmount();
            	   }
               }
               else if (incidental.getCity().equals("") && incidental.getState().equals("") && !incidental.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(breakfast.getCountry());
            	   Double incidentalPerDiem = perDiemInfo.get(RATE_FIELDS.INCIDENTAL_CEILING.ordinal());
            	   if (incidental.getAmount() > incidentalPerDiem)
            	   {
            		   throw new TrapException("Incidental limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += incidental.getAmount();
                	   totalReimbursement += incidental.getAmount();
            	   }
               }
               else if (!incidental.getCity().equals("") && incidental.getState().equals("") && !incidental.getCountry().equals(""))
               {
            	   List<Double> perDiemInfo = perDiemDB.getDomesticPerDiem(incidental.getCity(), incidental.getCountry());
            	   Double incidentalPerDiem = perDiemInfo.get(RATE_FIELDS.INCIDENTAL_CEILING.ordinal());
            	   if (incidental.getAmount() > incidentalPerDiem)
            	   {
            		   throw new TrapException("Incidental limit exceeded");
            	   }
            	   else 
            	   {
                	   dayTotal += incidental.getAmount();
                	   totalReimbursement += incidental.getAmount();
            	   }
               }
              
               this.addToOutputMap("DAY"+Integer.toString(i+1)+"_TOTAL", Double.toString(dayTotal));

           		if(myFormData.get("DAY" + Integer.toString(i) + "_INCIDENTAL_AMOUNT") != null)
           		{
           			this.addToOutputMap("DAY"+Integer.toString(i+1)+"_INCIDENTAL_TOTAL", Double.toString(incidental.getAmount()));
           			this.addToOutputMap("DAY"+Integer.toString(i+1)+"_INCIDENTAL_JUSTIFICATION", incidental.getJustification());
           		}
            }

	    	// add transportation        
            for (int i = 0; i < transportation.size(); i++)
            {
            	Transportation transport = transportation.get(i);
            	double transportAmount = transport.getAmount();
                this.addToOutputMap("TRANSPORTATION"+Integer.toString(i+1)+"_DATE", transport.getDate());
                this.addToOutputMap("TRANSPORTATION"+Integer.toString(i+1)+"_TYPE", transport.getType());
                
                this.addToOutputMap("TRANSPORTATION"+Integer.toString(i+1)+"_TOTAL", String.format("%.2f", transportAmount));
                totalReimbursement += transportAmount;  
            }
            
	    	// add other expenses     
            for (int i = 0; i < otherExpenses.size(); i++)
            {
            	OtherExpenses otherExps = otherExpenses.get(i);
            	double otherExpstAmount = otherExps.getAmount();
                this.addToOutputMap("OTHER"+Integer.toString(i+1)+"_DATE", otherExps.getDate());
                this.addToOutputMap("OTHER"+Integer.toString(i+1)+"_JUSTIFICATION", otherExps.getJustification());
                this.addToOutputMap("OTHER"+Integer.toString(i+1)+"_TOTAL", String.format("%.0f", otherExpstAmount));
                totalReimbursement += otherExpstAmount; 
            }
          
	    	// add grants        
            for (int i = 0; i < grants.size(); i++)
            {     	
            	Grant grant =  grants.get(i);
    	    	List<String> grantUserInfo = userGrantDB.getUserGrantInfo((grant.getAccountNumber()));
    	    	this.addToOutputMap("GRANT"+Integer.toString(i+1)+"_ACCOUNT", (grant.getAccountNumber()));
    	    	this.addToOutputMap("GRANT"+Integer.toString(i+1)+"_PERCENT", Integer.toString(grant.getPercentCharged()));
    	    	String approverName = grantUserInfo.get(USER_GRANT_FIELDS.GRANT_ADMIN.ordinal());
    	    	this.addToOutputMap("GRANT"+Integer.toString(i+1)+"_APPROVER_NAME", approverName);
    	    	double amountToCharge = (grant.getPercentCharged()/100.0) * totalReimbursement;
    	    	this.addToOutputMap("GRANT"+Integer.toString(i+1)+"_AMOUNT_TO_CHARGE", String.format("%.2f", amountToCharge));
                List<Object> grantInfo = grantDB.getGrantInfo(String.valueOf(grant.getAccountNumber()));
                int index = GRANT_FIELDS.ACCOUNT_BALANCE.ordinal();
                String temp = grantInfo.get(index).toString();
                double balance = Double.parseDouble(temp);
                double newBalance = balance - amountToCharge;
    	    	grantDB.updateAccountBalance((grant.getAccountNumber()), newBalance);
            }
            
            this.addToOutputMap("TOTAL_REIMBURSEMENT", String.format("%.2f", totalReimbursement));
           
    	} 
    	catch (KeyNotFoundException e) 
    	{
			e.printStackTrace();
			throw new TrapException("User Grant info not found");
		} 
    	
    	
        return this.myFormOutput;
    }
}

